package com.abeir.bilibili.cmmand;
import org.apache.commons.cli.*;

public class CliCommander implements Commander{

    private final org.apache.commons.cli.Options options = new org.apache.commons.cli.Options();
    private final HelpFormatter formatter = new HelpFormatter();

    private String name;
    private Callback callback;

    public CliCommander(){
        init();
    }

    private void init(){
        options.addOption("h", "help", false, "Display usage information");
    }

    @Override
    public void registerCommand(String shortCommand, String longCommand, boolean hasArg, String help) {
        options.addOption(shortCommand, longCommand, hasArg, help);
    }

    @Override
    public void setApplicationName(String name) {
        this.name = name;
    }

    @Override
    public void setCallback(Callback callback) {
        this.callback = callback;
    }

    @Override
    public void usage() {
        formatter.printHelp("java -jar " + name + ".jar", options);
    }

    @Override
    public boolean parse(String[] args) throws Exception {
        CommandLineParser parser = new DefaultParser();
        CommandLine cmd = parser.parse(options, args);

        if(cmd.hasOption("help")){
            usage();
            return false;
        }
        if(callback != null){
            try{
                callback.call(new CliOptions(cmd));
                return true;
            } catch (OptionException e) {
                System.out.println(e.getMessage());
                System.out.println();
                usage();
            }
        }
        return false;
    }


    private static class CliOptions implements Options{

        private final CommandLine cmd;

        public CliOptions(CommandLine cmd){
            this.cmd = cmd;
        }

        @Override
        public boolean hasOption(String name) {
            return cmd.hasOption(name);
        }

        @Override
        public String getValue(String name) {
            return cmd.getOptionValue(name);
        }

        @Override
        public String[] getValues(String name) {
            return cmd.getOptionValues(name);
        }
    }
}
